package 剑指offer;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: tyy 剑指 Offer
 * 476. 数字的补数
 *对整数的二进制表示取反（0 变 1 ，1 变 0）后，再转换为十进制表示，可以得到这个整数的补数。
    例如，整数 5 的二进制表示是 "101" ，取反后得到 "010" ，再转回十进制表示得到补数 2 。
    给你一个整数 num ，输出它的补数。
    示例 1：
    输入：num = 5
    输出：2
    解释：5 的二进制表示为 101（没有前导零位），其补数为 010。所以你需要输出 2 。
 * @create: 2021-10-18 17:40
 * @description:
 **/
public class Solution5 {
    public static int convertBinaryToDecimal(long num)
    {
        int decimalNumber = 0, i = 0;
        long remainder;
        while (num != 0)
        {
            remainder = num % 10; // num最后一位数
            num /= 10;
            decimalNumber += remainder * Math.pow(2, i); // 最后一位是0则是0，是1则是2的i次方
            ++i;
        }
        return decimalNumber;
    }
    public int findComplement(int num) {
        String s = Integer.toBinaryString(num);
        char[] chars = s.toCharArray();
        char[] temps = new char[chars.length];
        for (int i = 0; i < chars.length; i++) {
            temps[i] = chars[i] == '1' ? '0' : '1';
        }
        String s1 = String.valueOf(temps);
        Long value = Long.valueOf(s1);
        int decimal = convertBinaryToDecimal(value);
        System.out.printf("%d 二进制 = %d 十进制", num, decimal);

        return decimal;

    }

    public int findComplement1(int num) {
        long ans=1;
        while(ans<=num){ans*=2;}
        return (int)ans-1-num;

//        int bitCount = 31;
//        while ((num & (1<<bitCount)) == 0) --bitCount; // 统计二进制位数
//        return (~num)&((1<<(bitCount+1))-1);
    }

    public int findComplement2(int num) {
        int t = 1;
        int sum=0;
        while(num>0){
            if((num&1)==0){
                sum+=t;
            }
            t*=2;
            num>>=1;
        }
        return sum;
    }
    public static void main(String[] args) {
        int complement = new Solution5().findComplement(20161211);
        System.out.println("complement = " + complement);
    }
}

